#include "../../../include/common/service_discovery/service_registry.h"
#include "../../../include/common/logger/logger.h"

#include <thread>
#include <chrono>
#include <nlohmann/json.hpp>

// 服务注册表的TTL（秒）
constexpr int SERVICE_TTL = 30;

ServiceRegistry::ServiceRegistry(std::shared_ptr<RedisClient> redisClient) 
    : redisClient_(redisClient), heartbeatRunning_(false) {
    LOG_INFO("Service Registry initialized");
}

ServiceRegistry::~ServiceRegistry() {
    stopHeartbeat();
    
    // 注销所有本地注册的服务
    for (const auto& entry : localRegistry_) {
        deregisterService(entry.first);
    }
}

bool ServiceRegistry::registerService(const ServiceInstance& instance) {
    try {
        std::string serviceKey = generateServiceKey(instance.serviceId, instance.host + ":" + std::to_string(instance.port));
        
        // 创建服务实例JSON
        nlohmann::json serviceData;
        serviceData["serviceId"] = instance.serviceId;
        serviceData["host"] = instance.host;
        serviceData["port"] = instance.port;
        serviceData["version"] = instance.version;
        serviceData["metadata"] = instance.metadata;
        
        // 将服务实例信息存储到Redis，设置TTL
        bool success = redisClient_->setWithExpire(serviceKey, serviceData.dump(), SERVICE_TTL);
        
        if (success) {
            // 保存到本地注册表
            std::lock_guard<std::mutex> lock(mutex_);
            localRegistry_[serviceKey] = instance;
            LOG_INFO("Service registered: " + instance.serviceId + " at " + instance.host + ":" + std::to_string(instance.port));
        }
        
        return success;
    } catch (const std::exception& e) {
        LOG_ERROR("Failed to register service: " + std::string(e.what()));
        return false;
    }
}

bool ServiceRegistry::deregisterService(const std::string& serviceId) {
    std::lock_guard<std::mutex> lock(mutex_);
    
    // 找到所有匹配的服务实例
    std::vector<std::string> keysToRemove;
    for (const auto& entry : localRegistry_) {
        if (entry.second.serviceId == serviceId) {
            keysToRemove.push_back(entry.first);
        }
    }
    
    bool success = true;
    // 从Redis和本地注册表中删除
    for (const auto& key : keysToRemove) {
        if (redisClient_->del(key)) {
            localRegistry_.erase(key);
            LOG_INFO("Service deregistered: " + key);
        } else {
            success = false;
            LOG_ERROR("Failed to deregister service: " + key);
        }
    }
    
    return success;
}

std::vector<ServiceInstance> ServiceRegistry::getServiceInstances(const std::string& serviceName) {
    std::vector<ServiceInstance> instances;
    
    try {
        // 使用Redis的模式匹配查找所有服务实例
        std::string pattern = "service:" + serviceName + ":*";
        auto keys = redisClient_->keys(pattern);
        
        for (const auto& key : keys) {
            std::string value = redisClient_->get(key);
            if (!value.empty()) {
                nlohmann::json data = nlohmann::json::parse(value);
                
                ServiceInstance instance;
                instance.serviceId = data["serviceId"];
                instance.host = data["host"];
                instance.port = data["port"];
                instance.version = data["version"];
                
                // 解析metadata
                for (const auto& item : data["metadata"].items()) {
                    instance.metadata[item.key()] = item.value();
                }
                
                instances.push_back(instance);
            }
        }
    } catch (const std::exception& e) {
        LOG_ERROR("Failed to get service instances: " + std::string(e.what()));
    }
    
    return instances;
}

void ServiceRegistry::startHeartbeat() {
    if (!heartbeatRunning_) {
        heartbeatRunning_ = true;
        std::thread t(&ServiceRegistry::heartbeatThread, this);
        t.detach();
        LOG_INFO("Service heartbeat started");
    }
}

void ServiceRegistry::stopHeartbeat() {
    heartbeatRunning_ = false;
    LOG_INFO("Service heartbeat stopped");
}

std::string ServiceRegistry::generateServiceKey(const std::string& serviceName, const std::string& serviceId) {
    return "service:" + serviceName + ":" + serviceId;
}

void ServiceRegistry::heartbeatThread() {
    while (heartbeatRunning_) {
        try {
            // 对所有本地注册的服务更新TTL
            std::lock_guard<std::mutex> lock(mutex_);
            for (const auto& entry : localRegistry_) {
                updateServiceTTL(entry.first);
            }
        } catch (const std::exception& e) {
            LOG_ERROR("Heartbeat error: " + std::string(e.what()));
        }
        
        // 每SERVICE_TTL/2秒发送一次心跳
        std::this_thread::sleep_for(std::chrono::seconds(SERVICE_TTL / 2));
    }
}

void ServiceRegistry::updateServiceTTL(const std::string& serviceKey) {
    try {
        std::string value = redisClient_->get(serviceKey);
        if (!value.empty()) {
            redisClient_->setWithExpire(serviceKey, value, SERVICE_TTL);
        }
    } catch (const std::exception& e) {
        LOG_ERROR("Failed to update service TTL: " + std::string(e.what()));
    }
} 